﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AdaptiveAgents.Loggers
{    
    /// <summary>
    /// A class used to write data to the log files. 
    /// </summary>
    public class FileLogger : Logger
    {
        private String fileName; 
        private StreamWriter fout; //Output to file

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name">File name to write into</param>
        public FileLogger(String name)
        {
            fileName = name;
            try
            {
                // Open a file stream writer
                fout = new StreamWriter(fileName);
                
                //Writes the file header
                //Write(MessageType.HackMessage, String.Format("Starting File {0}", name) + System.EnvironmentType.NewLine);
            }
            // Catches any error conditions
            catch (IOException e)
            {
                System.Console.Error.WriteLine("Unable to write to file: " + fileName);
                System.Diagnostics.Debug.Assert(false);
            }
        }

        /// <summary>
        /// Close the file
        /// </summary>
        public override void Close()
        {
            try
            {
                fout.Close();
            }
            catch (IOException e)
            {
                System.Console.Error.WriteLine("Problem closing file: " + fileName);
            }
        }

        /// <summary>
        /// Writes a message accroding to different types and data.
        /// </summary>
        /// <param name="message">message type</param>
        /// <param name="newLine">indication of writing a new line character after current message</param>
        /// <param name="p">array of data objects to be written</param>
        protected override void writeInternal(MessageType message, bool newLine, params object[] p)
        {
            bool isWrite = true;

            switch (message)
            {
                case MessageType.Performence:
                    fout.Write(LogTemplate.PERFORMANCE_REPORT, p);
                    break;
                case MessageType.NextPerformer:
                    fout.Write(LogTemplate.NEXT_PERFORMER, p);
                    break;
                case MessageType.GameStats:
                    fout.Write(LogTemplate.GAME_STATS, p);
                    break;
                case MessageType.LineSeperator:
                    fout.Write(System.Environment.NewLine);
                    break;
                case MessageType.NewLine:
                    fout.WriteLine();
                    break;
                case MessageType.ObservationsHeader:
                    fout.Write(LogTemplate.OBSERVATIONS_OF_AGENT, p);
                    break;
                case MessageType.NumActions:
                    fout.Write(LogTemplate.NUM_OF_ACTIONS_OF_AGENT, p);
                    break;
                default:
                    isWrite = false; //Used when we should ignore the message according to the given type
                    break;
            }

            if (newLine && isWrite)
                fout.WriteLine();
        }
    }

}
